home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1995 October
/
EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso
/
Aminet
/
dev
/
gui
/
BGUI11c.lha
/
ARexxClass
/
ARexxClass.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-23
|
37KB
|
1,011 lines
/*
** File: arexxclass.c
** Description: BOOPSI ARexx interface class.
** Copyright: (C) Copyright 1994-1995 Jaba Development.
** (C) Copyright 1994-1995 Jan van den Baard.
** All Rights Reserved.
**/
/*
** Uncomment the following line if you want the
** class to use memory pools and you have got
** the 3.1 amiga.lib. You need the 3.1 amiga.lib
** because the earlier version do not contain
** link versions of the pool routines.
**/
/* #define POOLS */
/*
** When POOLS is defined the class will
** use the allocation routines as defined
** in the source. Otherwise it simply
** allocates memory from the system pool.
**/
#ifdef POOLS
#define AllocMemory(s) GetMem( ad, s )
#define FreeMemory(p) PutMem( ad, p )
#else
#define AllocMemory(s) AllocVec( s, MEMF_PUBLIC | MEMF_CLEAR )
#define FreeMemory(p) FreeVec( p )
#endif
/*
** Include necessary headers.
**/
#include "ARexxClass.h"
#include <proto/intuition.h>
#include <proto/utility.h>
#include <proto/rexxsyslib.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <clib/alib_protos.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/*
** Compiler crap. Should compile under SAS this way...
**/
#ifdef _DCC
#define SAVEDS __geta4
#define ASM
#define REG(x) __ ## x
#else
#define SAVEDS __saveds
#define ASM __asm
#define REG(x) register __ ## x
#endif
/*
** Object instance data. Every object
** created from this class has this
** data.
**/
typedef struct {
struct MsgPort *ad_Port; /* Host message port. */
UBYTE *ad_HostName; /* Host name. */
UBYTE *ad_FileExt; /* File extention. */
ULONG ad_PendCnt; /* Messages still un-reply'd. */
REXXCOMMAND *ad_Commands; /* Host command list. */
struct RDArgs *ad_DOSParser; /* ReadArgs() parser. */
UWORD ad_Flags; /* See below. */
#ifdef POOLS
APTR ad_MemPool; /* Memory pool. */
#endif
} AD;
/*
** Static module prototypes of functions
** defined after they are referenced.
**/
STATIC ULONG SAVEDS ASM ARexxDispatch( REG(A0) Class *cl, REG(A2) Object *obj, REG(A1) Msg );
/*
** Class initialization. Simply creates the
** class and set's up the dispatcher.
**/
Class *InitARexxClass( void )
{
Class *cl;
if ( cl = MakeClass( NULL, ROOTCLASS, NULL, sizeof( AD ), 0L ))
cl->cl_Dispatcher.h_Entry = (HOOKFUNC)ARexxDispatch;
return( cl );
}
/*
** Free the class. A simply FreeClass()
** would suffice but in the future this
** may do more.
**/
BOOL FreeARexxClass( Class *cl )
{
return( FreeClass( cl ));
}
/*
** These routines are only compiled when
** POOLS is defined. In that case the memory
** allocations are done in the object it's
** memory pool.
**/
#ifdef POOLS
/*
** Pool allocation.
**/
STATIC APTR GetMem( AD *ad, ULONG size )
{
ULONG *ptr;
/*
** Allocate the memory. Size is tracked so we do not
** need to remember it when deallocating the memory again.
**/
if ( ptr = LibAllocPooled( ad->ad_MemPool, size + sizeof( ULONG ))) {
/*
** Store allocation size.
**/
*ptr = size + sizeof( ULONG );
/*
** Adjust pointer.
**/
ptr++;
}
return(( APTR )ptr );
}
/*
** Pool freeing.
**/
STATIC VOID PutMem( AD *ad, APTR mem )
{
ULONG *ptr = ( ULONG * )mem;
/*
** Retrieve the original allocation.
**/
ptr--;
/*
** Deallocate.
**/
LibFreePooled( ad->ad_MemPool, ptr, *ptr );
}
#endif
/*
** Duplicate a string.
**/
STATIC UBYTE *DupStr( AD *ad, UBYTE *str )
{
UBYTE *dup = AllocMemory( strlen( str ) + 1 );
/*
** Allocation OK?
**/
if ( dup )
/*
** Copy the string.
**/
strcpy( dup, str );
return( dup );
}
/*
** Reply a rexx command.
**/
STATIC VOID ReplyRexxCommand( struct RexxMsg *rxm, LONG prim, LONG sec, UBYTE *res )
{
UBYTE buf[ 16 ];
/*
** Result wanted?
**/
if ( rxm->rm_Action & RXFF_RESULT ) {
/*
** Primary result?
**/
if ( ! prim ) {
/*
** We setup the secondary result to
** the result string when one was passed.
**/
sec = res ? ( LONG )CreateArgstring( res, strlen( res )) : 0L;
} else {
/*
** Primary result bigger than 0?
**/
if ( prim > 0 ) {
/*
** Setup the result field
** to point to a string containing
** the secondary result number.
**/
sprintf( buf, "%ld", sec );
res = buf;
} else {
/*
** Negate primary result and
** setup the result field to
** the secondary result.
**/
prim = -prim;
res = ( UBYTE * )sec;
}
/*
** Setup ARexx it's "RC2" variable to
** the result.
**/
SetRexxVar(( struct Message * )rxm, "RC2", res, strlen( res ));
/*
** Clear secondary result.
**/
sec = 0L;
}
} else if ( prim < 0 )
/*
** Negate primary result.
**/
prim = -prim;
/*
** Setup result fields.
**/
rxm->rm_Result1 = prim;
rxm->rm_Result2 = sec;
/*
** Reply the RexxMsg.
**/
ReplyMsg(( struct Message * )rxm );
}
/*
** Free a RexxMsg command.
**/
STATIC VOID FreeRexxCommand( struct RexxMsg *rxm )
{
/*
** Delete the result Argstring.
**/
if ( ! rxm->rm_Result1 && rxm->rm_Result2 )
DeleteArgstring(( UBYTE * )rxm->rm_Result2 );
/*
** Close input handle.
**/
if ( rxm->rm_Stdin && rxm->rm_Stdin != Input()) {
/*
** If the output handle is the
** same as the input handle we
** can safely clear it.
**/
if ( rxm->rm_Stdout == rxm->rm_Stdin )
rxm->rm_Stdout = NULL;
Close( rxm->rm_Stdin );
rxm->rm_Stdin = NULL;
}
/*
** Close output handle if it is not
** the same as Stdin.
**/
if ( rxm->rm_Stdout && rxm->rm_Stdout != Output()) {
Close( rxm->rm_Stdout );
rxm->rm_Stdout = NULL;
}
/*
** Delete the command Argstring.
**/
DeleteArgstring(( UBYTE * )ARG0( rxm ));
/*
** Delete the message itself.
**/
DeleteRexxMsg( rxm );
}
/*
** Create a RexxMsg command.
**/
STATIC struct RexxMsg *CreateRexxCommand( AD *ad, UBYTE *comname, BPTR handle )
{
struct RexxMsg *rxm;
/*
** Create the RexxMsg.
**/
if ( rxm = CreateRexxMsg( ad->ad_Port, ad->ad_FileExt, ad->ad_HostName )) {
/*
** Create the Argstring.
**/
if ( rxm->rm_Args[ 0 ] = CreateArgstring( comname, strlen( comname ))) {
/*
** Setup action flags.
**/
rxm->rm_Action = RXCOMM | RXFF_RESULT;
/*
** Setup file handles.
**/
rxm->rm_Stdin = rxm->rm_Stdout = handle;
return( rxm );
}
/*
** Argstring creation failed.
**/
DeleteRexxMsg( rxm );
}
return( NULL );
}
/*
** Send a RexxMsg command to the
** ARexx server.
**/
STATIC struct RexxMsg *CommandToRexx( AD *ad, struct RexxMsg *rxm )
{
struct MsgPort *rxp;
/*
** Try to find the "REXX"
** message port.
**/
Forbid();
if ( ! ( rxp = FindPort( RXSDIR ))) {
/*
** Oops. ARexx server
** not active.
**/
Permit();
return( NULL );
}
/*
** Send off the message.
**/
PutMsg( rxp, &rxm->rm_Node );
Permit();
/*
** Increase pending counter.
**/
ad->ad_PendCnt++;
return( rxm );
}
/*
** Send a command to the ARexx server.
**/
STATIC struct RexxMsg *SendRexxCommand( AD *ad, UBYTE *comname, BPTR handle )
{
struct RexxMsg *rxm;
/*
** Create a RexxMsg command and
** send it off to the ARexx server.
**/
if ( rxm = CreateRexxCommand( ad, comname, handle ))
return( CommandToRexx( ad, rxm ));
return( NULL );
}
STATIC REXXCOMMAND *FindRXCommand( AD *ad, UBYTE *comname, UWORD len )
{
REXXCOMMAND *rc = ad->ad_Commands;
while ( rc->rc_Func ) {
if ( ! strnicmp( comname, rc->rc_Name, len ) && isspace( comname[ strlen( rc->rc_Name ) ] ))
return( rc );
rc++;
}
return( NULL );
}
/*
** Execute a command.
**/
STATIC VOID DoRXCommand( AD *ad, struct RexxMsg *rxm )
{
struct RexxMsg *rm;
REXXCOMMAND *rco;
REXXARGS *ra;
UBYTE *comname, *args, *tmp, *result = NULL;
LONG rc = 20, rc2 = 0;
UWORD numargs = 0, len = 0;
/*
** Allocate memory for the command
** name and it's argument string.
**/
if ( ! ( comname = ( UBYTE * )AllocMemory( strlen(( UBYTE * )ARG0( rxm )) + 2 ))) {
rc2 = ERROR_NO_FREE_STORE;
return;
}
/*
** Copy command name and argument string.
**/
strcpy( comname, ( UBYTE * )ARG0( rxm ));
/*
** ReadArgs() requires the argument
** string to end with a newline.
**/
strcat( comname, "\n" );
/*
** Find the length of the command
** the start of the arguments.
**/
args = comname;
while ( isspace( *args )) args++;
tmp = args;
while ( ! isspace( *args )) { len++; args++; }
/*
** Find the command.
**/
if ( rco = FindRXCommand( ad, tmp, len )) {
/*
** Allocate REXXARGS structure.
**/
if ( ra = ( REXXARGS * )AllocMemory( sizeof( REXXARGS ))) {
/*
** Count number of expected args.
**/
if ( rco->rc_ArgTemplate ) {
tmp = rco->rc_ArgTemplate;
while ( *tmp != '\n' ) {
if ( *tmp++ == ',' ) numargs++;
}
numargs++;
/*
** Allocate arg array.
**/
if ( ra->ra_ArgList = ( ULONG * )AllocMemory( numargs * sizeof( ULONG ))) {
/*
** Setup RDArgs.
**/
ad->ad_DOSParser->RDA_Source.CS_Buffer = args;
ad->ad_DOSParser->RDA_Source.CS_Length = strlen( args );
ad->ad_DOSParser->RDA_Source.CS_CurChr = 0;
ad->ad_DOSParser->RDA_DAList = NULL;
ad->ad_DOSParser->RDA_Buffer = NULL;
/*
** Parse args.
**/
if ( ReadArgs( rco->rc_ArgTemplate, ra->ra_ArgList, ad->ad_DOSParser )) {
/*
** Call the REXX routine.
**/
( rco->rc_Func )( ra, rxm );
rc = ra->ra_RC;
rc2 = ra->ra_RC2;
result = ra->ra_Result;
FreeArgs( ad->ad_DOSParser );
} else {
rc = 10;
rc2 = IoErr();
}
FreeMemory( ra->ra_ArgList );
} else
rc2 = ERROR_NO_FREE_STORE;
} else {
/*
** No args.
**/
( rco->rc_Func )( ra, rxm );
rc = ra->ra_RC;
rc2 = ra->ra_RC2;
result = ra->ra_Result;
}
FreeMemory( ra );
} else
rc2 = ERROR_NO_FREE_STORE;
} else {
/*
** Not found in our list?
** Maybe it's a script.
**/
if ( rm = CreateRexxCommand( ad, ( UBYTE * )ARG0( rxm ), NULL )) {
/*
** Save original message.
**/
rm->rm_Args[ 15 ] = ( STRPTR )rxm;
/*
** Let the REXX server see what
** it can do with this.
**/
if ( ! CommandToRexx( ad, rm ))
rc2 = ERROR_NOT_IMPLEMENTED;
} else
rc2 = ERROR_NO_FREE_STORE;
goto byeBye;
}
ReplyRexxCommand( rxm, rc, rc2, result );
byeBye:
FreeMemory( comname );
}
/*
** OM_NEW.
**/
STATIC ULONG ARexxNew( Class *cl, Object *obj, struct opSet *ops )
{
struct TagItem *attr = ops->ops_AttrList, *tag;
struct MsgPort *mp;
AD *ad;
ULONG rc, *ecode, ext = 1L;
UBYTE unique_name[ 80 ], *tmp;
/*
** Let the superclass set us up...
**/
if ( rc = ( ULONG )DoSuperMethodA( cl, obj, ( Msg )ops )) {
/*
** Get the instance data.
**/
ad = ( AD * )INST_DATA( cl, rc );
/*
** Safety precautions.
**/
bzero(( char * )ad, sizeof( AD ));
/*
** First see if we got error storage.
**/
if ( tag = FindTagItem( AC_ErrorCode, attr ))
ecode = ( ULONG * )tag->ti_Data;
#ifdef POOLS
/*
** Create a memory pool.
**/
if ( ad->ad_MemPool = LibCreatePool( MEMF_PUBLIC | MEMF_CLEAR, 4096L, 4096L )) {
#endif
/*
** Create port if a
** host name is supplied.
**/
if ( tag = FindTagItem( AC_HostName, attr )) {
/*
** Store host name.
**/
ad->ad_HostName = ( UBYTE * )tag->ti_Data;
/*
** Name valid?
**/
if ( ad->ad_HostName && *ad->ad_HostName ) {
/*
** Make the name unique.
**/
sprintf( unique_name, "%s.1", ad->ad_HostName );
Forbid();
while (( mp = FindPort( unique_name )) && ext <= 99 )
sprintf( unique_name, "%s.%ld", ad->ad_HostName, ++ext );
Permit();
/*
** Name unique?
**/
if ( ! mp ) {
/*
** Copy the name.
**/
if ( ad->ad_HostName = DupStr( ad, unique_name )) {
/*
** Uppercase it.
**/
tmp = ad->ad_HostName;
while ( *tmp ) {
*tmp = toupper( *tmp );
tmp++;
}
/*
** Create the port.
**/
if ( ad->ad_Port = CreateMsgPort()) {
/*
** Initialize and add the port.
**/
ad->ad_Port->mp_Node.ln_Name = ad->ad_HostName;
ad->ad_Port->mp_Node.ln_Pri = 0;
AddPort( ad->ad_Port );
} else if ( ecode )
*ecode = RXERR_OUT_OF_MEMORY;
} else if ( ecode )
*ecode = RXERR_OUT_OF_MEMORY;
} else if ( ecode )
*ecode = RXERR_PORT_ALREADY_EXISTS;
} else if ( ecode )
*ecode = RXERR_NO_PORT_NAME;
} else if ( ecode )
*ecode = RXERR_NO_PORT_NAME;
/*
** Do we have a port now?
**/
if ( ad->ad_Port ) {
/*
** Find the commandlist.
**/
if ( tag = FindTagItem( AC_CommandList, attr )) {
if ( ad->ad_Commands = ( REXXCOMMAND * )tag->ti_Data ) {
/*
** Setup the AmigaDOS parser.
**/
if ( ad->ad_DOSParser = ( struct RDArgs * )AllocDosObject( DOS_RDARGS, NULL )) {
ad->ad_DOSParser->RDA_Flags = RDAF_NOPROMPT;
/*
** Obtain file extention.
**/
if ( tag = FindTagItem( AC_FileExtention, attr ))
ad->ad_FileExt = ( UBYTE * )tag->ti_Data;
else
ad->ad_FileExt = "rexx";
return( rc );
} else if ( ecode )
*ecode = RXERR_OUT_OF_MEMORY;
} else if ( ecode )
*ecode = RXERR_NO_COMMAND_LIST;
} else if ( ecode )
*ecode = RXERR_NO_COMMAND_LIST;
}
#ifdef POOLS
} else if ( ecode )
*ecode = RXERR_OUT_OF_MEMORY;
#endif
/*
** Bliep error...bliep....
**/
CoerceMethod( cl, ( Object * )rc, OM_DISPOSE );
}
return( 0L );
}
/*
** OM_DISPOSE.
**/
STATIC ULONG ARexxDispose( Class *cl, Object *obj, Msg msg )
{
AD *ad = ( AD * )INST_DATA( cl, obj );
struct RexxMsg *rxm;
/*
** Do we have a port?
**/
if ( ad->ad_Port ) {
/*
** Remove the port from the public list
**/
RemPort( ad->ad_Port );
/*
** Wait for and handle all
** messages still pending.
**/
if ( ad->ad_PendCnt ) {
while ( ad->ad_PendCnt ) {
/*
** Wait for a message.
**/
WaitPort( ad->ad_Port );
/*
** Get messages.
**/
while ( rxm = ( struct RexxMsg * )GetMsg( ad->ad_Port )) {
/*
** Replyed message?
**/
if ( rxm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG ) {
/*
** Free the message and decrease the
** pending counter.
**/
FreeRexxCommand( rxm );
ad->ad_PendCnt--;
} else
/*
** Tell'm where getting out of here.
**/
ReplyRexxCommand( rxm, -20, ( LONG )"Host object closing down", NULL );
}
}
} else {
/*
** In case there are no messages pending we
** still need to reply all that is waiting at
** the port.
**/
while ( rxm = ( struct RexxMsg * )GetMsg( ad->ad_Port ))
ReplyRexxCommand( rxm, -20, ( LONG )"Host object closing down", NULL );
}
/*
** Delete the port.
**/
DeleteMsgPort( ad->ad_Port );
}
/*
** Delete the AmigaDOS parser.
**/
if ( ad->ad_DOSParser )
FreeDosObject( DOS_RDARGS, ad->ad_DOSParser );
/*
** Delete the port name.
**/
if ( ad->ad_HostName )
FreeMemory( ad->ad_HostName );
#ifdef POOLS
/*
** Free the pool.
**/
LibDeletePool( ad->ad_MemPool );
#endif
/*
** Let the superclass do the rest.
**/
return( DoSuperMethodA( cl, obj, msg ));
}
/*
** ACM_EXECUTE.
**/
STATIC ULONG ARexxExecute( Class *cl, Object *obj, struct acmExecute *acme )
{
AD *ad = ( AD * )INST_DATA( cl, obj );
REXXCOMMAND *rco;
REXXARGS *ra;
struct RexxMsg *rxm;
UBYTE *args, *tmp, *result = NULL, *com;
UWORD numargs = 0, len = 0;
ULONG r = 20, r2;
/*
** Allocate a private copy of the command string.
**/
if ( com = ( UBYTE * )AllocMemory( strlen( acme->acme_CommandString ) + 2 )) {
/*
** Make a copy terminated with a newline.
**/
strcpy( com, acme->acme_CommandString );
strcat( com, "\n" );
/*
** Find the length of the command
** and the start of the arguments.
**/
args = com;
while ( isspace( *args )) args++;
tmp = args;
while ( ! isspace( *args )) { len++; args++; }
/*
** Look up the command.
**/
if ( rco = FindRXCommand( ad, tmp, len )) {
/*
** Allocate a REXXARGS structure.
**/
if ( ra = ( REXXARGS * )AllocMemory( sizeof( REXXARGS ))) {
/*
** Args expected?
**/
if ( rco->rc_ArgTemplate ) {
/*
** Count the expected number of arguments.
**/
tmp = rco->rc_ArgTemplate;
while ( *tmp != '\n' ) {
if ( *tmp++ != ',' ) numargs++;
}
numargs++;
/*
** Allocate space to parse the args.
**/
if ( ra->ra_ArgList = ( ULONG * )AllocMemory( numargs * sizeof( ULONG ))) {
/*
** Setup the parser.
**/
ad->ad_DOSParser->RDA_Source.CS_Buffer = args;
ad->ad_DOSParser->RDA_Source.CS_Length = strlen( args );
ad->ad_DOSParser->RDA_Source.CS_CurChr = 0;
ad->ad_DOSParser->RDA_DAList = NULL;
ad->ad_DOSParser->RDA_Buffer = NULL;
/*
** Parse the args.
**/
if ( ReadArgs( rco->rc_ArgTemplate, ra->ra_ArgList, ad->ad_DOSParser )) {
/*
** Run command.
**/
( rco->rc_Func )( ra, NULL );
/*
** Store results.
**/
r = ra->ra_RC;
r2 = ra->ra_RC2;
result = ra->ra_Result;
FreeArgs( ad->ad_DOSParser );
} else {
r = 10;
r2 = IoErr();
}
/*
** Deallocate arg list.
**/
FreeMemory( ra->ra_ArgList );
} else
r2 = ERROR_NO_FREE_STORE;
} else {
/*
** Run command.
**/
( rco->rc_Func )( ra, NULL );
/*
** Store results.
**/
r = ra->ra_RC;
r2 = ra->ra_RC2;
result = ra->ra_Result;
}
/*
** Deallocate the REXXARGS structure.
**/
FreeMemory( ra );
} else
r2 = ERROR_NO_FREE_STORE;
/*
** When not passed to the rexx server
** we must close the given IO handle
** ourselves.
**/
if ( acme->acme_IO ) Close( acme->acme_IO );
} else {
/*
** We do not send the new-line to
** the ARexx server.
**/
com[ strlen( com ) - 1 ] = '\0';
/*
** Unknown commands are shipped
** off to the REXX server.
**/
if ( rxm = CreateRexxCommand( ad, com, acme->acme_IO )) {
if ( ! CommandToRexx( ad, rxm ))
r2 = ERROR_NOT_IMPLEMENTED;
else
r = r2 = 0L;
} else
r2 = ERROR_NO_FREE_STORE;
}
/*
** Deallocate the command copy.
**/
FreeMemory( com );
} else
r2 = ERROR_NO_FREE_STORE;
/*
** Put the results into their
** storage spaces.
**/
if ( acme->acme_RC ) *( acme->acme_RC ) = r;
if ( acme->acme_RC2 ) *( acme->acme_RC2 ) = r2;
if ( acme->acme_Result ) *( acme->acme_Result ) = result;
return( 1L );
}
/*
** OM_GET.
**/
STATIC ULONG ARexxGet( Class *cl, Object *obj, struct opGet *opg )
{
AD *ad = ( AD * )INST_DATA( cl, obj );
ULONG rc = 1L;
/*
** What do they want?
**/
switch ( opg->opg_AttrID ) {
case AC_HostName:
*( opg->opg_Storage ) = ( ULONG )ad->ad_HostName;
break;
case AC_RexxPortMask:
*( opg->opg_Storage ) = ( 1L << ad->ad_Port->mp_SigBit );
break;
default:
rc = DoSuperMethodA( cl, obj, ( Msg )opg );
break;
}
return( rc );
}
/*
** ACM_HANDLE_EVENT.
**/
STATIC ULONG ARexxHandleEvent( Class *cl, Object *obj, Msg msg )
{
struct RexxMsg *rxm, *org;
AD *ad = ( AD * )INST_DATA( cl, obj );
ULONG rc = 1L;
/*
** Get the messages from the port.
**/
while ( rxm = ( struct RexxMsg * )GetMsg( ad->ad_Port )) {
/*
** A Rexx command?
**/
if (( rxm->rm_Action & RXCODEMASK ) != RXCOMM )
ReplyMsg(( struct Message * )rxm );
else if ( rxm->rm_Node.mn_Node.ln_Type == NT_REPLYMSG ) {
/*
** Reply'd message. See if it was started
** as a script.
**/
if ( org = ( struct RexxMsg * )rxm->rm_Args[ 15 ] ) {
if ( rxm->rm_Result1 )
ReplyRexxCommand( org, 20, ERROR_NOT_IMPLEMENTED, NULL );
else
ReplyRexxCommand( org, 0, 0, ( UBYTE * )rxm->rm_Result2 );
}
/*
** Free the message and decrease the
** pending counter.
**/
FreeRexxCommand( rxm );
ad->ad_PendCnt--;
} else if ( ARG0( rxm ))
/*
** Execute message.
**/
DoRXCommand( ad, rxm );
else
ReplyMsg(( struct Message * )rxm );
}
}
/*
** Class dispatcher.
**/
STATIC SAVEDS ASM ULONG ARexxDispatch( REG(A0) Class *cl, REG(A2) Object *obj, REG(A1) Msg msg )
{
ULONG rc = 0L;
/*
** Evaluate the method.
**/
switch ( msg->MethodID ) {
case OM_NEW:
rc = ARexxNew( cl, obj, ( struct opSet * )msg );
break;
case OM_GET:
rc = ARexxGet( cl, obj, ( struct opGet * )msg );
break;
case OM_DISPOSE:
rc = ARexxDispose( cl, obj, msg );
break;
case ACM_HANDLE_EVENT:
rc = ARexxHandleEvent( cl, obj, msg );
break;
case ACM_EXECUTE:
rc = ARexxExecute( cl, obj, ( struct acmExecute * )msg );
break;
default:
rc = DoSuperMethodA( cl, obj, msg );
break;
}
return ( rc );
}